package integral

import (
	"context"
	"fmt"
	"strconv"
	"strings"
	"time"

	"mall/common/cachex"
	"mall/common/globalkey"
	"mall/common/jwt"
	"mall/common/resultx"
	"mall/service/backend/common/utils/pointy"
	"mall/service/forum/api/internal/svc"
	"mall/service/forum/api/internal/types"
	"mall/service/user/rpc/userclient"

	"github.com/zeromicro/go-zero/core/logx"
)

type TodayRemainingIntegralLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// 获取用户今日可获取积分
func NewTodayRemainingIntegralLogic(ctx context.Context, svcCtx *svc.ServiceContext) *TodayRemainingIntegralLogic {
	return &TodayRemainingIntegralLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *TodayRemainingIntegralLogic) TodayRemainingIntegral() (resp *types.TodayRemainingIntegralResp, err error) {
	userId := jwt.GetUserId(l.ctx)
	if userId == 0 {
		return nil, resultx.NewErrCode(resultx.TOKEN_EXPIRE_ERROR)
	}
	uid := strconv.FormatUint(userId, 10)

	stockKey := l.getStockKey()
	result, err := l.svcCtx.BizRedis.HgetCtx(l.ctx, stockKey, uid)
	if err != nil && err.Error() != "redis: nil" {
		return nil, err
	}
	if len(strings.TrimSpace(result)) > 0 {
		points, err := strconv.ParseUint(result, 10, 64)
		if err != nil {
			return nil, err
		}
		return &types.TodayRemainingIntegralResp{
			RemainingPoints: pointy.GetPointer(points),
		}, nil
	}

	//无缓存，查mysql更新缓存
	now := time.Now()
	// 获取当天的起始时间（午夜）
	startOfDay := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	// 获取当天的终止时间（午夜前的最后一秒）
	endOfDay := startOfDay.AddDate(0, 0, 1).Add(-time.Second)
	var filters []string
	filters = append(filters, "UserId,equalTo:"+strconv.FormatInt(int64(userId), 10))
	filters = append(filters, "Status,equalTo:"+strconv.FormatInt(int64(globalkey.StatusEnabled), 10))
	filters = append(filters, "UpdatedAt,moreThanOrEqualTo:"+startOfDay.Format("2006-01-02"))
	filters = append(filters, "UpdatedAt,lessThan:"+endOfDay.Format("2006-01-02"))
	userTaskLog, err := l.svcCtx.UserRpc.GetIntegralTaskLogList(l.ctx, &userclient.BaseListReq{
		Filter: pointy.GetPointer(strings.Join(filters, ";")),
	})
	if err != nil {
		return nil, nil
	}
	points := uint64(0)
	if len(userTaskLog.List) > 0 {
		for _, v := range userTaskLog.List {
			if v.Integrals != nil && *v.Integrals > 0 {
				points += *v.Integrals
			}
		}
	}
	remainingPoints := uint64(l.svcCtx.Config.Query.MaxPoints) - points

	//更新缓存
	err = l.svcCtx.BizRedis.HsetCtx(l.ctx, stockKey, uid, strconv.FormatUint(remainingPoints, 10))
	if err != nil {
		return nil, err
	}

	return &types.TodayRemainingIntegralResp{
		RemainingPoints: pointy.GetPointer(remainingPoints),
	}, nil
}
func (l *TodayRemainingIntegralLogic) getStockKey() string {
	// task:remaining:integral:1:2025-03-14
	return fmt.Sprintf("{%s}:%s", cachex.RemainingIntegral, time.Now().Format("2006-01-02"))
}
